package com.littlerpc.protocol.codec.protobuf;

import com.littlerpc.protocol.codec.Serializer;
import io.protostuff.*;
import io.protostuff.runtime.RuntimeSchema;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 *
 * @author ChengPeng
 * @date 2017/7/10
 */
public class ProtobufSerializer implements Serializer {

    private Map<Class<?>,Schema<?>> cacheSchema = new ConcurrentHashMap<>();

    @Override
    public <T> byte[] serialize(T obj) {
        //获取类的描述
        Schema<T> schema = getSchema((Class<T>) obj.getClass());
        return ProtostuffIOUtil.toByteArray(obj,schema, LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));
    }

    @Override
    public <T> T deserialize(byte[] bytes, Class<T> clazz) {
        Schema<T> schema = getSchema(clazz);
        T message = schema.newMessage();
        ProtostuffIOUtil.mergeFrom(bytes,message,schema);
        return message;
    }

    private <T> Schema<T> getSchema(Class<T> aClass) {

        if(cacheSchema.containsKey(aClass)) {
            return (Schema<T>) cacheSchema.get(aClass);
        }

        RuntimeSchema<T> schema = RuntimeSchema.createFrom(aClass);
        if(schema != null) {
            cacheSchema.putIfAbsent(aClass,schema);
        }
        return schema;


    }

}
